import { Tabs } from 'antd'
import { useEffect, useState } from 'react'
import { useRef } from 'react'

import {
  getAppMenuTreeApi,
  getAppMenuTreeByRoleIdApi,
  getMenuByRoleIdApi,
  getMenuTreeApi,
  getWardPermissionTreeApi,
  getWardPermissionTreeByRoleIdApi,
  saveAppMenuTreeApi,
  saveMenuTreeApi,
  saveWardPermissionTreeApi,
} from '@/api/sys/roleManage'
import AekDrawer, { PromiseThen } from '@/components/AekDrawer'
import { requestWithTry } from '@/utils/request'

import MenuTree from './MenuTree'

const TREE_KEY = 'menuId'
const TREE_TITLE = 'menuName'

/** 将功能按钮和菜单分开 */
const renameChildrenConditionally = arr => {
  if (!Array.isArray(arr)) return []
  for (let obj of arr) {
    if (!Array.isArray(obj.children)) continue
    // 检查当前children数组的所有子元素是否全为type:1
    const permissionList = obj.children.filter(child => child.type === 1)
    const childrenWithoutPermission = obj.children.filter(child => child.type === 0)
    if (permissionList.length) {
      obj.permissionList = permissionList
      obj.children = childrenWithoutPermission
    }
    // 继续递归处理未满足条件的children子元素
    renameChildrenConditionally(obj.children)
  }
  return arr
}

/** 重命名数据权限的数据结构 */
const renameWardPermission = wardPermissionTree => {
  wardPermissionTree.forEach(item => {
    item.menuList?.forEach(menu => {
      menu[TREE_KEY] = menu.hospitalId
      menu[TREE_TITLE] = menu.name
      menu.children = menu.areaList
      menu.children?.forEach(subMenu => {
        subMenu[TREE_KEY] = `${menu[TREE_KEY]}-${subMenu.areaId}`
        subMenu[TREE_TITLE] = subMenu.name
        subMenu.children = subMenu.wardList
        subMenu.children?.forEach(grandsonMenu => {
          grandsonMenu[TREE_KEY] = `${subMenu[TREE_KEY]}-${grandsonMenu.wardId}`
          grandsonMenu[TREE_TITLE] = grandsonMenu.name
        })
      })
    })
  })
}

const SetPermissionsDrawer = ({ row = {} }) => {
  const { roleId } = row

  const [loading, setLoading] = useState(false)
  const [tabs, setTabs] = useState([])

  const childRefList = useRef([])

  const getAllPermission = async () => {
    setLoading(true)
    const [menuTree, appMenuTree, wardPermissionTree, checkedMenuTree, checkedAppMenuTree, checkedWardPermissionTree] =
      await Promise.all([
        // 获取全部权限树
        requestWithTry(getMenuTreeApi).then(res => res.data),
        requestWithTry(getAppMenuTreeApi).then(res => res.data),
        requestWithTry(getWardPermissionTreeApi).then(res => res.data),
        // 获取当前角色的权限树
        requestWithTry(getMenuByRoleIdApi, { roleId }).then(res => res.data),
        requestWithTry(getAppMenuTreeByRoleIdApi, { roleId }).then(res => res.data),
        requestWithTry(getWardPermissionTreeByRoleIdApi, { roleId }).then(res => res.data),
      ]).finally(() => setLoading(false))
    renameWardPermission(wardPermissionTree)
    renameWardPermission(checkedWardPermissionTree)
    const tabs = menuTree.map(({ entranceId, entranceName, menuList }, index) => ({
      key: entranceId,
      label: entranceName,
      subTabs: [
        {
          key: 'menu',
          label: '菜单权限',
          menuTree: renameChildrenConditionally(menuList),
          checkedMenuTree: renameChildrenConditionally(checkedMenuTree[index]?.menuList || []),
        },
        {
          key: 'appMenu',
          label: '菜单权限(APP)',
          menuTree: renameChildrenConditionally(appMenuTree[index].menuList),
          checkedMenuTree: renameChildrenConditionally(checkedAppMenuTree[index]?.menuList || []),
        },
        {
          key: 'wardPermission',
          label: '数据权限',
          menuTree: renameChildrenConditionally(wardPermissionTree[index].menuList),
          checkedMenuTree: renameChildrenConditionally(checkedWardPermissionTree[index]?.menuList || []),
        },
      ],
    }))
    setTabs(tabs)
  }

  useEffect(() => {
    getAllPermission()
  }, [])

  const onOk = async () => {
    const menuCheckedKeys = []
    const appMenuCheckedKeys = []
    const wardPermissionCheckedKeys = []
    childRefList.current.forEach(subMap => {
      Object.keys(subMap).forEach(key => {
        if (key === 'menu') {
          const { allCheckedKeys, permissionCheckedKeys } = subMap[key].getAllCheckedKeys()
          menuCheckedKeys.push(...allCheckedKeys, ...permissionCheckedKeys)
        }
        if (key === 'appMenu') {
          const { allCheckedKeys, permissionCheckedKeys } = subMap[key].getAllCheckedKeys()
          appMenuCheckedKeys.push(...allCheckedKeys, ...permissionCheckedKeys)
        }
        if (key === 'wardPermission') {
          const { allCheckedKeys } = subMap[key].getAllCheckedKeys()
          // 只需要把病区的id返回给后端
          allCheckedKeys.forEach(key => {
            const [hospitalId, areaId, wardId] = `${key}`.split('-')
            if (!wardId) return
            wardPermissionCheckedKeys.push(wardId)
          })
        }
      })
    })
    await Promise.all([
      requestWithTry(saveMenuTreeApi, { roleId, roleMenuList: menuCheckedKeys }),
      requestWithTry(saveAppMenuTreeApi, { roleId, roleMenuList: appMenuCheckedKeys }),
      requestWithTry(saveWardPermissionTreeApi, { roleId, roleMenuList: wardPermissionCheckedKeys }),
    ])
  }

  return (
    <AekDrawer title='角色权限设置' width='90%' onOk={onOk} loading={loading}>
      <Tabs
        tabPosition='left'
        animated
        items={tabs.map((item, i) => ({
          key: item.key,
          label: item.label,
          forceRender: true,
          children: (
            <Tabs
              animated
              items={item.subTabs.map(subItem => ({
                key: subItem.key,
                label: subItem.label,
                forceRender: true,
                children: (
                  <MenuTree
                    ref={el => {
                      if (!childRefList.current[i]) {
                        childRefList.current[i] = {}
                      }
                      childRefList.current[i][subItem.key] = el
                    }}
                    treeData={subItem.menuTree}
                    checkedTreeData={subItem.checkedMenuTree}
                  />
                ),
              }))}
            />
          ),
        }))}
      />
    </AekDrawer>
  )
}

SetPermissionsDrawer.PromiseThen = PromiseThen

export default SetPermissionsDrawer
